from hashlib import md5
import bcrypt
from sqlalchemy import or_, select
from app.core.exception import ApiException
from app.entity.blackToken import BlackToken
from app.entity.user import User
from app.service.blackToken import BlackTokenService
from app.utils.CaptchaUtils import CaptchaUtils
from app.utils.JwtUtils import JwtUtils
from app.utils.MyUtils import generate_random_string


class UserService:
    
    @staticmethod
    def login(username,password:str,loginType:int,captchaKey:str,captchaValue:str):
        user=User().query().where(User.phone==username).with_entities(User.id).first()
        if user == None:
            user=User().query().where(User.username==username).with_entities(User.id).first()
        if user == None:
            raise ApiException("用户名或密码不一致")
        user:User=User().query().where(User.id==user.id).one()
        if loginType==0:
            if not bcrypt.checkpw(password.encode(),user.password.encode()):
                raise ApiException("用户名或密码不一致")
        elif loginType==1:
            if not CaptchaUtils.verify(captchaKey,captchaValue):
                raise ApiException("验证码错误")
        token=JwtUtils.createUserToken(user.id)
        pyload=JwtUtils.decodeToken(token)
        return token,user,pyload['exp']
        
    def searchUser(keyword:str):
        return User().query().where(User.status=="Y").\
            where(or_(User.phone==keyword,User.username==keyword,User.nickname.like("%"+keyword+"%")))\
                .with_entities(User.id,User.nickname,User.avatarUrl,User.username).all()

    def logout(token):
        BlackTokenService.addBlackToken(token)
    
    def getUserByToken(token)->User:
        tokenData=JwtUtils.decodeToken(token)
        return User().query().where(User.id==tokenData["userId"]).one()

    def chkInfoUpdValue(field,value,userid):
        if field=="username":
            cnt=User().query().where(User.username==value).where(User.id!=userid).count()
            if cnt>0:
                raise ApiException("用户名已存在")


    @staticmethod
    def register(data:dict):
        count=User().query().where(User.phone==data['phone']).count()
        if count>0:
            raise ApiException("电话号码已存在！")
        if not CaptchaUtils().verify(data['captchaKey'],data['captchaVal']):
            raise ApiException("验证码错误")
        user=User()
        user.phone=data['phone']
        user.status="Y"
        user.password=bcrypt.hashpw(data['password'].encode(),bcrypt.gensalt()).decode()
        user.username=generate_random_string(10)
        user.nickname='小记账'+user.username
        user.save()
        md5str=md5((str(user.id)+user.username).encode())
        user.qrcode= md5str.hexdigest()
        user.save()

    def checkLogin(self,token):
        BlackTokenService.checkToken(token)
        JwtUtils.decodeToken(token)
        return True
    
    def isValidUser(userid)->User:
        user:User=User().query().where(User.id==userid).one()
        if user==None:
            raise ApiException("用户不存在")
        if user.status!="Y":
            raise ApiException("用户已冻结")
        if user.deletedAt!=None:
            raise ApiException("用户不存在")
        return user
    
